package com.eastfair.common.controller.micetother;

import cn.hutool.core.util.StrUtil;
import com.eastfair.common.consts.CrmConstants;
import com.eastfair.common.dto.*;
import com.eastfair.common.service.CrmCustomerInfoSyncService;
import com.eastfair.common.service.CrmPersonSyncService;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.venuebooking.api.ContactFeign;
import com.eastfair.venuebooking.vo.ContactVO;
import core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * CRM同步个人信息.
 *
 * @author dqq
 * @date 2023 /2/2
 */
@Component
@Slf4j
public class CrmPersonSyncTask {

    @Value("${com.eastfair.projectId}")
    private Long projectId;

    @Resource
    private ContactFeign contactFeign;

    @Resource
    private CrmPersonSyncService crmPersonSyncService;

    @Resource
    private CrmCustomerInfoSyncService crmCustomerInfoSyncService;

    @Resource(name = "threadPoolTaskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 同步CRM个人信息.
     */
    // @Scheduled(cron = "0/10 * * * * *")
    @XxlJob("syncPersonal")
    public void syncPersonal() throws InterruptedException {
        log.info("syncPersonal - 同步CRM个人信息");
        // 查询联系人数据
        ContextUtil.setProjectId(projectId);
        R<List<ContactVO>> r = contactFeign.queryForSyncCms();
        if (!r.getIsSuccess()) {
            throw BizException.wrap(r.getCode(), r.getMsg());
        }
        List<ContactVO> contactVOList = r.getData();
        if (contactVOList == null || contactVOList.isEmpty()) {
            log.info("syncPersonal - 没有待同步的个人信息");
            return;
        }
        // 同步个人信息
        syncPersonal(contactVOList);
        CountDownLatch countDownLatch = new CountDownLatch(3);
        // 同步客户名称
        threadPoolTaskExecutor.execute(() -> {
            syncCustomerInfo(contactVOList);
            countDownLatch.countDown();
        });
        // 同步地址地址
        threadPoolTaskExecutor.execute(() -> {
            syncCustomerAddressInfo(contactVOList);
            countDownLatch.countDown();
        });
        // 同步客户联系方式
        threadPoolTaskExecutor.execute(() -> {
            syncCustomerContractInfo(contactVOList);
            countDownLatch.countDown();
        });
        boolean await = countDownLatch.await(1, TimeUnit.MINUTES);
        if (!await) {
            throw BizException.wrap(-1, "同步个人以及客户信息超时，不更新cms同步标识");
        }
        // 更新用户信息为已同步
        List<Long> contactIds = contactVOList
                .stream()
                .map(ContactVO::getId)
                .collect(Collectors.toList());
        contactFeign.updateHasSyncCrm(contactIds);
    }

    /**
     * 同步个人信息.
     *
     * @param contactVOList the contact vo list
     */
    public void syncPersonal(List<ContactVO> contactVOList) {
        List<GmApiIdvInfDto> list = new ArrayList<>();
        for (ContactVO contactVO : contactVOList) {
            GmApiIdvInfDto gmApiIdvInfDto = new GmApiIdvInfDto();
            // 证件号码没有，传主键ID
            gmApiIdvInfDto.setCrdtNo(contactVO.getId() + "");
            gmApiIdvInfDto.setCrdtTpcd(CrmConstants.CRDT_TPCD);
            gmApiIdvInfDto.setCstId(contactVO.getId() + "");
            gmApiIdvInfDto.setCstNm(contactVO.getContactName());
            gmApiIdvInfDto.setCtcInfCntnt(contactVO.getMobile());
            gmApiIdvInfDto.setDtSrc(CrmConstants.DT_SRC);
            gmApiIdvInfDto.setDelInd("0");
            // 性别
            String gender = contactVO.getGender();
            if (StrUtil.isBlank(gender)) {
                gmApiIdvInfDto.setGndCd("03");
            } else if ("MALE".equals(gender)) {
                gmApiIdvInfDto.setGndCd("01");
            } else if ("FEMALE".equals(gender)) {
                gmApiIdvInfDto.setGndCd("02");
            } else {
                gmApiIdvInfDto.setGndCd("03");
            }
            // 生日
            LocalDate birthday = contactVO.getBirthday();
            if (birthday != null) {
                Instant instant = birthday.atTime(LocalTime.MIDNIGHT).atZone(ZoneId.systemDefault()).toInstant();
                Date birthdayDate = Date.from(instant);
                gmApiIdvInfDto.setBrthDt(birthdayDate);
            }
            list.add(gmApiIdvInfDto);
        }
        GmApiIdvInfDtos gmApiIdvInfDtos = new GmApiIdvInfDtos();
        gmApiIdvInfDtos.setDtos(list);
        // 同步个人信息
        crmPersonSyncService.syncPersonalInfo(gmApiIdvInfDtos);
    }

    /**
     * 同步客户名称.
     *
     * @param contactVOList the contact vo list
     */
    public void syncCustomerInfo(List<ContactVO> contactVOList) {
        // 同步客户名称
        List<GmApiCstNmInfDto> gmApiCstNmInfDtoList = new ArrayList<>();
        for (ContactVO contactVO : contactVOList) {
            GmApiCstNmInfDto gmApiCstNmInfDto = new GmApiCstNmInfDto();
            gmApiCstNmInfDto.setCrdtNo(contactVO.getId() + "");
            gmApiCstNmInfDto.setCrdtTpcd(CrmConstants.CRDT_TPCD);
            gmApiCstNmInfDto.setCstId(contactVO.getId() + "");
            gmApiCstNmInfDto.setCstNm(contactVO.getContactName());
            gmApiCstNmInfDto.setDtSrc(CrmConstants.DT_SRC);
            gmApiCstNmInfDto.setDelInd("0");
            gmApiCstNmInfDtoList.add(gmApiCstNmInfDto);
        }
        GmApiCstNmInfDtos gmApiCstNmInfDtos = new GmApiCstNmInfDtos();
        gmApiCstNmInfDtos.setDtos(gmApiCstNmInfDtoList);
        crmCustomerInfoSyncService.syncCustomerInfo(gmApiCstNmInfDtos);
    }

    /**
     * 同步客户地址.
     *
     * @param contactVOList the contact vo list
     */
    public void syncCustomerAddressInfo(List<ContactVO> contactVOList) {
        // 同步客户地址
        List<GmApiCstAdrInfDto> gmApiCstAdrInfDtoList = new ArrayList<>();
        for (ContactVO contactVO : contactVOList) {
            GmApiCstAdrInfDto gmApiCstAdrInfDto = new GmApiCstAdrInfDto();
            gmApiCstAdrInfDto.setCrdtNo(contactVO.getId() + "");
            gmApiCstAdrInfDto.setCrdtTpcd(CrmConstants.CRDT_TPCD);
            gmApiCstAdrInfDto.setCstId(contactVO.getId() + "");
            // 行政区域
            String region = contactVO.getRegion();
            if (StrUtil.isNotBlank(region)) {
                String[] regionArray = StrUtil.split(region, ",");
                for (int i = 0; i < regionArray.length; i++) {
                    if (i == 0) {
                        gmApiCstAdrInfDto.setProvCd(regionArray[i]);
                    }
                    if (i == 1) {
                        gmApiCstAdrInfDto.setCityCd(regionArray[i]);
                    }
                    if (i == 2) {
                        gmApiCstAdrInfDto.setCntyanddstcCd(regionArray[i]);
                    }
                }
            }
            if (StrUtil.isNotBlank(contactVO.getAddress())) {
                gmApiCstAdrInfDto.setDtlAdr(contactVO.getAddress());
            } else {
                gmApiCstAdrInfDto.setDtlAdr("无");
            }
            gmApiCstAdrInfDto.setDtSrc(CrmConstants.DT_SRC);
            gmApiCstAdrInfDto.setDelInd("0");
            gmApiCstAdrInfDtoList.add(gmApiCstAdrInfDto);
        }
        GmApiCstAdrInfDtos gmApiCstAdrInfDtos = new GmApiCstAdrInfDtos();
        gmApiCstAdrInfDtos.setDtos(gmApiCstAdrInfDtoList);
        crmCustomerInfoSyncService.syncCustomerAddressInfo(gmApiCstAdrInfDtos);
    }

    /**
     * 同步客户联系方式.
     *
     * @param contactVOList the contact vo list
     */
    public void syncCustomerContractInfo(List<ContactVO> contactVOList) {
        // 同步客户联系方式
        List<GmApiCstCtcInfDto> gmApiCstCtcInfDtoList = new ArrayList<>();
        for (ContactVO contactVO : contactVOList) {
            GmApiCstCtcInfDto gmApiCstCtcInfDto = new GmApiCstCtcInfDto();
            gmApiCstCtcInfDto.setCrdtNo(contactVO.getId() + "");
            gmApiCstCtcInfDto.setCrdtTpcd(CrmConstants.CRDT_TPCD);
            gmApiCstCtcInfDto.setCstId(contactVO.getId() + "");
            gmApiCstCtcInfDto.setCtcInfCntnt(contactVO.getMobile());
            gmApiCstCtcInfDto.setDtSrc(CrmConstants.DT_SRC);
            gmApiCstCtcInfDto.setDelInd("0");
            gmApiCstCtcInfDtoList.add(gmApiCstCtcInfDto);
        }
        GmApiCstCtcInfDtos gmApiCstCtcInfDtos = new GmApiCstCtcInfDtos();
        gmApiCstCtcInfDtos.setDtos(gmApiCstCtcInfDtoList);
        crmCustomerInfoSyncService.syncCustomerContractInfo(gmApiCstCtcInfDtos);
    }
}